#pragma once
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <chrono>
#include <iomanip>
#include <print>
#include <ctime>  // 用于时间处理
#include <cstdio> // 用于跨平台兼容

// 跨平台线程安全的本地时间转换函数
inline bool safe_localtime(const std::time_t* time, std::tm* result) {
#ifdef _MSC_VER
    // Windows平台使用localtime_s（线程安全）
    return localtime_s(result, time) == 0;
#else
    // POSIX平台（Linux/macOS）使用localtime_r（线程安全）
    return localtime_r(time, result) != nullptr;
#endif
}

class CSVExporter {
private:
    std::stringstream buffer;  // 缓存待写入的数据
    std::string filePath;      // CSV 文件路径
    size_t flushThreshold = 100; // 触发刷盘的记录数阈值
    size_t recordCount = 0;    // 当前缓存的记录数
    bool fileValid = false;    // 文件是否有效

public:
    // 构造函数：初始化文件路径并写入表头
    CSVExporter(const std::string& path, const std::string& header)
        : filePath(path) {

        std::ofstream file(filePath);
        if (file.is_open()) {
            file << std::setprecision(7); // 设置文件流精度
            file << header << "\n";
            fileValid = true;
        }
        else {
            fileValid = false;
            std::print("无法创建 CSV 文件: {}", path);
        }
    }

    // 添加仅含时间戳的记录
    void AddRecord(const std::chrono::system_clock::time_point& now) {
        if (!fileValid) return;

        auto now_time_t = std::chrono::system_clock::to_time_t(now);
        auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()).count() % 1000;

        // 线程安全的本地时间转换
        std::tm local_tm{};
        if (!safe_localtime(&now_time_t, &local_tm)) {
            std::print("时间转换失败");
            return;
        }

        // 格式化时间戳（包含毫秒）
        std::stringstream ss;
        ss << std::put_time(&local_tm, "%Y-%m-%dT%H:%M:%S")
            << "." << std::setfill('0') << std::setw(3) << now_ms;

        buffer << ss.str() << "\n";
        recordCount++;

        if (recordCount >= flushThreshold) {
            Flush();
        }
    }

    // 添加时间戳+数值列表的记录
    void AddRecord(const std::chrono::system_clock::time_point& now, const std::vector<double>& values) {
        if (!fileValid) return;

        auto now_time_t = std::chrono::system_clock::to_time_t(now);
        auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()).count() % 1000;

        std::tm local_tm{};
        if (!safe_localtime(&now_time_t, &local_tm)) {
            std::print("时间转换失败");
            return;
        }

        std::stringstream ss;
        ss << std::put_time(&local_tm, "%Y-%m-%dT%H:%M:%S")
            << "." << std::setfill('0') << std::setw(3) << now_ms;

        buffer << std::setprecision(10);
        buffer << ss.str();

        for (double value : values) {
            buffer << "," << value;
        }

        buffer << "\n";
        recordCount++;

        if (recordCount >= flushThreshold) {
            Flush();
        }
    }

    // 添加时间戳+字符串+数值列表的记录
    void AddRecord(const std::chrono::system_clock::time_point& now, const std::string& v, const std::vector<double>& values) {
        if (!fileValid) return;

        auto now_time_t = std::chrono::system_clock::to_time_t(now);
        auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
            now.time_since_epoch()).count() % 1000;

        std::tm local_tm{};
        if (!safe_localtime(&now_time_t, &local_tm)) {
            std::print("时间转换失败");
            return;
        }

        std::stringstream ss;
        ss << std::put_time(&local_tm, "%Y-%m-%dT%H:%M:%S")
            << "." << std::setfill('0') << std::setw(3) << now_ms;

        buffer << std::setprecision(10);
        buffer << ss.str() << "," << v;

        for (double value : values) {
            buffer << "," << value;
        }

        buffer << "\n";
        recordCount++;

        if (recordCount >= flushThreshold) {
            Flush();
        }
    }

    // 手动刷盘
    void Flush() {
        if (!fileValid || buffer.tellp() <= 0) return;

        std::ofstream file(filePath, std::ios::app);
        if (file.is_open()) {
            file << std::setprecision(7);
            file << buffer.str();
            buffer.str(""); // 清空缓存
            recordCount = 0;
        }
        else {
            fileValid = false;
            std::print("无法追加写入 CSV 文件: {}", filePath);
        }
    }

    // 析构函数：确保最终数据刷盘
    ~CSVExporter() {
        if (fileValid) {
            Flush();
        }
    }
};
